{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "view-in-github"
      },
      "source": [
        "<a href=\"https://colab.research.google.com/github/SingTown/openmv_tensorflow_training_scripts/blob/main/mnist/openmv_mnist.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "L0HImeGrETRa"
      },
      "source": [
        "# Train mnist and Save to OpenMV\n",
        "\n",
        "This Code is for TensorFlow 2\n",
        "\n",
        "reference: https://keras.io/examples/vision/mnist_convnet/"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 8,
      "metadata": {
        "id": "xpN0Op4AEP-6"
      },
      "outputs": [],
      "source": [
        "import numpy as np\n",
        "from tensorflow import keras\n",
        "from tensorflow.keras import layers\n",
        "import matplotlib.pyplot as plt"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "jwzfGEUiFQcw"
      },
      "source": [
        "# Prepare Dataset"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 9,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "SJHbc4TLE-kx",
        "outputId": "c951216a-f568-41e8-ca19-98664bd46f2d"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "x_train shape: (60000, 28, 28, 1)\n",
            "60000 train samples\n",
            "10000 test samples\n"
          ]
        }
      ],
      "source": [
        "# Model / data parameters\n",
        "num_classes = 10\n",
        "input_shape = (28, 28, 1)\n",
        "\n",
        "# Load the data and split it between train and test sets\n",
        "(x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()\n",
        "\n",
        "# Scale images to the [0, 1] range\n",
        "x_train = x_train.astype(\"float32\") / 255\n",
        "x_test = x_test.astype(\"float32\") / 255\n",
        "# Make sure images have shape (28, 28, 1)\n",
        "x_train = np.expand_dims(x_train, -1)\n",
        "x_test = np.expand_dims(x_test, -1)\n",
        "print(\"x_train shape:\", x_train.shape)\n",
        "print(x_train.shape[0], \"train samples\")\n",
        "print(x_test.shape[0], \"test samples\")\n",
        "\n",
        "\n",
        "# convert class vectors to binary class matrices\n",
        "y_train = keras.utils.to_categorical(y_train, num_classes)\n",
        "y_test = keras.utils.to_categorical(y_test, num_classes)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 13,
      "metadata": {},
      "outputs": [
        {
          "data": {
            "image/png": "iVBORw0KGgoAAAANSUhEUgAAAxoAAAMpCAYAAACDrkVRAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjEsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvc2/+5QAAAAlwSFlzAAAPYQAAD2EBqD+naQAAZsNJREFUeJzt/Qe4VNX1OO4fpItUKwiCigKKvcXeWyxgQ4m99469BnuNYosVsSAYC5YYG4mgH0ERRFEj2EAUCxaKiKDA75n5/82XuXt0DuO+d+7ced/n8dG9sufMMm7mzJpz1tn1FixYsCABAACIaLGYBwMAAMhQaAAAANEpNAAAgOgUGgAAQHQKDQAAIDqFBgAAEJ1CAwAAiK5Bmknz589PpkyZkjRv3jypV69e/CwoO5ntV2bOnJm0a9cuWWyx6q1XrT9Kuf4yrEEWZv1Ras7BlMv6S1VoZBZYhw4dYuVHHTJ58uSkffv21foe1h+lXH8Z1iD5WH+UmnMwtX39pSo0MlXsrwds0aJFnOwoazNmzMh+8Py6NqqT9Ucp11+GNcjCrD9KzTmYcll/qQqNXy+VZRaYRcbCauIyqvXHb6mpy/jWIPlYf5SaczC1ff1pBgcAAKJTaAAAANEpNAAAgOgUGgAAQHQKDQAAIDqFBgAAEJ1CAwAAiE6hAQAARKfQAAAAolNoAAAA0Sk0AACA6BQaAABAdAoNAAAgOoUGAAAQnUIDAACITqEBAABE1yD+IYGaNHr06CB28803B7EBAwbkjA8++OBgzoknnhjE1l133T+cIwBQeVzRAAAAolNoAAAA0Sk0AACA6BQaAABAdJrBFzJv3rwgNn369KKOla8Z98cff8wZjx8/Pphzyy23BLE+ffoEsYceeihn3KRJk2DO2WefHcQuuuii38ma2m7s2LFBbLvttgtiM2bMCGL16tXLGd93333BnCeeeCKIfffdd0VkCvEMHTo0iO2///4542HDhgVzunTpUq15Ud4uvfTSIHbhhRcGsQULFgSxl156KWe85ZZbRs4O6gZXNAAAgOgUGgAAQHQKDQAAILqy79H49NNPg9jcuXNzxq+++mow55VXXgli06ZNC2KPPPJIUl06dOiQasO0xx9/PIg1b948Z7zWWmsFc9wzWv5ef/31nPFee+2Vqo+oaj9GRosWLXLGjRo1CuZ88803QWzEiBFBbL311it4LH7b8OHDg9i3336bM95jjz1qMKPabdSoUUFs/fXXL0kulK977703Z3zllVcGc+rXr5+qfzPfZywQckUDAACITqEBAABEp9AAAACiU2gAAACV3Qz+5ptvBrFtttkm2iZ71a1qk1m+zYKaNWtWcGOqjHbt2uWMW7duHcyxWVXtVXXzxowxY8YEsQMOOCBnPGXKlKLfc5VVVskZn3nmmcGcfffdN4htuummQazq2j333HOLzqsSVd3sK+ODDz7IGVdqM/j8+fOD2CeffFLwQSD5NlWDhU2aNClnPGfOnJLlQu3z2muvBbH777+/4IM83nnnnVTHv+666373e1zGyy+/HMQOPPDAILbRRhsl5cIVDQAAIDqFBgAAEJ1CAwAAiE6hAQAAVHYzeMeOHYPYUkstVaPN4PkacPI1Yv/nP/8JYlV3T87X4ENlOProo4PYwIEDq/U9R48enTP+4YcfUu0mn69xedy4cZGzqywDBgwIYptssklJcqltvvjiiyB2xx13BLGqn59du3at1rwoLy+++GIQ69evX8HX5VtHTz/9dBBbdtll/0B2lNrgwYOD2MknnxzEpk6dWvChE1tttVUQ++abb4JYnz59CuaV7/j5jjVo0KCkXLiiAQAARKfQAAAAolNoAAAA0Sk0AACAym4Gb9OmTRC75pprgthTTz2VM15nnXWCOSeddFKq91x77bULNpjl2807306RaRrRqHuqNmH/VnNhmp2N8zWd7brrrqmazqruQprvz0XaBxvYhTn+7tf8/xxxxBFF7XRP5XrllVeC2CGHHBLEZsyYUfBYZ5xxRqoH0VB7/fLLLznjUaNGBXOOPPLIIDZr1qyCD0i54IILgjmbbbZZEMu363yvXr1yxs8991ySxvrrr5+UM1c0AACA6BQaAABAdAoNAACgsns08unZs2cQ22abbXLGzZs3D+a8/fbbQeyuu+4qeK97vn6MfLp3755q0ynqnrFjx+aMt9tuu1T3CterVy+I/fnPf84ZP/TQQ6k21LvssssK3vu+9NJLB3PWWmutVHn985//zBmPGTMmmLPuuusGsUqU77Pmq6++Kkku5WDatGmp5m2//fbVngvluwHmlClTiup5O+igg6LlRWk88MADOePDDz881et22GGHghv7tWjRougNAZ9L0ZPRoUOHIHbwwQcn5cwVDQAAIDqFBgAAEJ1CAwAAiE6hAQAARFf2zeD5pGnWadmyZapjVW0Q32+//YI5iy2mXqtUEyZMCGJXX311znj69OnBnHyN2G3bti3YBLbEEkuk2rAvXyymH3/8MWd87bXXBnMGDhxYrTmUi2eeeSaIzZ49uyS51Db5muInTpyY6rXLL798NWREbffNN98EsbvvvjuI1a9fP4i1atUqZ3z++edHzo6alu+/4eWXX17wgSbHH398ELv00kuDWNrm7zQPZEkj38bO+b4vlBPfkAEAgOgUGgAAQHQKDQAAIDqFBgAAEF2dbAZP4+KLLw5io0ePLrjr8osvvphqN0nqnjlz5hTcOT7frtn5msnuu+++ILb++uuXbdPw5MmTS51CrTV+/PhU81ZfffWk0uT78/Pll18GsS5dugSx5s2bV1te1B5VHw6w5557Fn2sE088MWe8zTbbFH0sal7fvn0LNn5nNG7cOGe84447BnOuuuqqINa0adOCOfz0009B7Pnnnw9ikyZNCmILFizIGV9wwQXBnB49eiR1jSsaAABAdAoNAAAgOoUGAAAQnUIDAACIrmKbwZs1axbE7rzzziC27rrr5oyPPPLIYM7WW2+dqrG36k6U+XarpPYaM2ZMwcbvfJ544okgtuWWW0bLi7phgw02SMrVjBkzgtizzz4bxB544IGCTZRpd/+tusszdVPVdTRu3LhUr9t2222D2MknnxwtL6rXtGnTgtitt94axPJ9j6ra/D1kyJCi8/jwww9zxvvvv38w54033kh1rH322SdnfOaZZyaVwBUNAAAgOoUGAAAQnUIDAACIrmJ7NPJZeeWVg9i9996bMz700ENTbb6WLzZr1qyc8UEHHRTMadu2bep8qVmnnXZawQ14Mrbaaqs61Y+R79+xmDn8vu+++y7asd56662c8fz584M5Q4cODWKfffZZEJs7d27O+MEHHwzm5Dt+vs2vNtpoo9/dWCvj559/TtXzRt2T7176s88+u+DrNt988yA2YMCAINayZcs/kB01qernTsbUqVNTvbZfv34546+//jqY079//1T9lO+++27OeObMman6RBZbLPwd/4ADDijYK1wXuaIBAABEp9AAAACiU2gAAADRKTQAAIDoNIMXsMcee+SMO3fuHMw5/fTTg9iLL74YxM4555yc8aRJk4I55513XhBbfvnlU+dLHE8//XQQGzt2bKomsN133z2pS/L9O1aNrb322jWYUXnJ1xSd7//To48+Omd8+eWXR2sGz9es37BhwyC2+OKLB7Fu3brljA877LBgznrrrVfwoQgZyy67bM64ffv2wZzZs2cHsa5duwYxytvEiROD2J577lnUsVZaaaWCa43y0qhRoyC2zDLLBLF8jd6dOnWKtjly1e9fLVq0COZMmTIliC211FJBbLfddksqkSsaAABAdAoNAAAgOoUGAAAQnUIDAACITjP4IlpjjTWC2MMPPxzEnnrqqSB2yCGH5Iz//ve/B3M++OCDIPbCCy8UkSl/RL6G1Hw7leZrTtt3332TcjBnzpwgdvHFF6d67bbbbpszvvLKK6PlVdfceuutQaxjx45B7NVXX432niussELOuEePHsGc1VZbLYj96U9/SqrTHXfcUbCRM19jL3XPVVddFcTq169f1LHS7B5OeWnVqlWqneN33XXXIPbtt98WfIhPvs/Eqt/RMtq0aZMz3m+//VI1g+ebV6lc0QAAAKJTaAAAANEpNAAAgOgUGgAAQHSawaupaenAAw8MYkcccUTO+Oeffw7mDB8+PIi99NJLqXbdpeY1adIkiLVt2zYph+bvSy+9NJhz9dVXB7EOHToEsdNPPz1nvMQSS0TJsVKcddZZSSUaOnRowTl77713jeRCzRk7dmwQe+6554o61u677x7EunTpUtSxKC8bbbRREJs6dWq1vmfV72TDhg0L5uTbedxDLf4fVzQAAIDoFBoAAEB0Cg0AACA6PRqL6O233w5ijzzySBAbNWpUEMvXk5FmE60ttthikXKk5uS7X7i23hNdtf9i8ODBqTYxeuyxxyJnB7+tZ8+epU6ByHbYYYcg9v333xd1X/6AAQOi5QWLunlvvn6MfDEb9v0/rmgAAADRKTQAAIDoFBoAAEB0Cg0AACA6zeALGT9+fBC76aabCjbGfvnll0W9X4MGDVJt9rbYYurBmrZgwYJUsSFDhgSxG2+8MalJ119/fRC75JJLgtj06dNzxgcccEAw57777oucHVDpvvnmmyBWv379VK89/vjjc8Y2B6Um7bjjjqVOoez5BgsAAESn0AAAAKJTaAAAANEpNAAAgOgqohk8X7P2wIEDg9jNN98cxCZOnBgtjw022CBnfN5555XNTtOVJu3un/nW1kknnZQzPuyww4I5Sy65ZBAbOXJkELv//vtzxm+9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X3211ClQZhYsWFDqFCDHAw88EMSuvPLKVA26c+fOLeo911577SDWsGHDoo5F7VW18Ttj8803zxk/9dRTNZgRdcHkyZOD2J133pnqYQS33HJLznjppZcuOo/TTjstZ/zwww8Hc5Zffvk6993RFQ0AACA6hQYAABCdQgMAAIhOoQEAAERXJ5vBY+rXr1/BXRvzNezWq1cv1a6TVW266aZBbOONN06RKXVR1XWUb11BVRMnTswZ33///cGcF198sahjv/zyy0Gs2HXZokWLIJZvt9w///nPQaxp06ZFvSdQt40bNy5nvOeeewZzpk6dGsROOumkILblllsWlcO1114bxO69996CrzvvvPOSusYVDQAAIDqFBgAAEJ1CAwAAiK4iejR+/PHHIPbuu+8Gsb59+waxf/7znwWPn7ZHo9DGghn9+/cPYvXr1y94LKAyVb0fOWP33XfPGX/66adJbbTFFlsEsaOOOqokuVC+vv3221KnQA345ZdfUm0gethhhxX1HW3EiBFB7PLLL88Zn3766cGc7777Loj94x//CGILquRx8MEHB3OOPvropK5xRQMAAIhOoQEAAESn0AAAAKJTaAAAANGVfTP4zz//HMTefPPNnPFee+0VzJkyZUoQW3zxxQs2bG+yySbBnGeffTaI5dvYr6p58+YFscceeyyInXzyyUGsUaNGBY8P8FvNkLXhWE899VQQe+aZZ1Jt2Ae/evLJJ0udAjVg0KBBQezwww8v6mE8q6yyShAbNWpUwVi+tfb555+n+o65zDLL5IzvueeepBK4ogEAAESn0AAAAKJTaAAAANEpNAAAgMpuBp87d26qRuw99tij4LEuvvjiILb11lsHsc0226zgDpDbbLNNqt16q/r666+D2Nlnnx3EVlhhhSDWs2fPnHHjxo0Lvh/lp9jG2+HDhwexE044IUJG1DZrrLFGEHvppZdyxvfff38wZ6eddgpiTZo0iZbX3XffHcT69esX7fhUhqrn5XwPEKDuGTx4cBA79NBDUz0Yp1WrVjnjgQMHBnNat24dxE477bQgNmzYsIIN42l3Hv/mm29yxh06dCj42Z2x8sorJ+XMFQ0AACA6hQYAABCdQgMAAIhOoQEAAFROM3i+Hb8vuuiiIHb11VcXPNbOO+8cxE488cSCDUQZU6dOLbhD7dtvvx3E8jVnn3nmmQUbxp944okg9pe//CWIbb/99r977N9qdspnnXXWSTWPmle1oSzNjqcZjz76aBB77733csarrbbaH8yO2qpjx4454/PPP7/Gc8j3wA3N4CyqfA9DSfOgmEmTJhX8c0HtdfvttwexfM3T+T7bDjvssKLe8+abbw5iRx11VM54xIgRSbHmz59f8AFE5d74nY8rGgAAQHQKDQAAIDqFBgAAUHd7NObNm5czvuCCC4I511xzTRBbYoklgtgVV1yRM+7du3eqfox8G7FU7eUYM2ZMMGfVVVcNYrfddlsQq3o/3owZM4I5r776ahB78MEHg9iTTz75uz0bi3K/6yeffJLqtdS8Y445puB9q2ndcccdOeMbbrih6GNBIc8991ypU6AOaNCg8NeUfBumzZkzp5oyoib06NEjiO25556p+jaKVXVDvYx333234OsGDRoUxLp3717wde3bt08qgSsaAABAdAoNAAAgOoUGAAAQnUIDAACou83gVRtV8zV+N2vWLIjla47dYYcdcsYjR44M5vTv3z+IPfPMM0Fs9uzZBTcNPPTQQ4tqUGrRokUQ22mnnVLFHnrooYIN4/n87W9/SzWP2qFbt26lToFatGlpvgbrbbfdNog1bdo0qUn33HNPEDvllFNqNAcqoym4a9euwZz3338/iOV72MWtt94aOTuqy8knn1ytx58+fXoQe/jhhwvO69y5czCnV69ekbOrW1zRAAAAolNoAAAA0Sk0AACA6BQaAABAdPUW5NtSs4rMDtYtW7bMNsXka2COoW3btjnjr7/+OpjTuHHjIJavMezHH3/MGX/wwQdF5/XXv/41Z3zOOecEc+rXr59UmppYE6V4r9ou3y70H374YarXVv2jnu91K6+8clIOanpN1MT7vfzyyznjyy+/PJjz/PPPB7GJEydW62653333XcGHZpx44ol5/z8rZPHFFw9iTz75ZBDbeuutk9qkLq6/cpHvIQP5Hu7y1VdfBbEmTZokdYVz8B9zxRVXBLHzzz8/iC2zzDI541GjRlXsDt/FrglXNAAAgOgUGgAAQHQKDQAAIDqFBgAAUHd3Bl9uueUKNoPPmTMniL311lsFj73LLrsEsS222CKI9ezZM4h16tQpqfTGb2qP1VdfPYh99NFHJcmFuKo2VI8bNy7V666++uog1rx582h5vfDCCznj0aNHB3Pq1auX6lhbbbVVzvi4446r9Y3f1H751l+jRo1Kkgu1z6RJk4LYnXfeGcQWWyz87f2oo45KKr3x+49yRQMAAIhOoQEAAESn0AAAAOpuj8bw4cNzxkOGDAnmjBkzpuBmKhmHHXZYzrh169bBHPdvUo6q3i/6WxucUTluvfXWUqeQ93N49913D2I33nhjnd1AjdLJbBpWVb7vEHvuuWcNZURtsv3226fq2zjwwAMLbtrMonNFAwAAiE6hAQAARKfQAAAAolNoAAAAdbcZvOoGU/macvLFoJKsttpqqWLvvfdeDWVELP37988Z33TTTcGcAQMGVGsOnTt3DmKLL754znjzzTcP5hx55JFBbI011oicHSTJ4MGDg1i+hwrk+1ykMh1yyCFB7IILLkj1AAv+OFc0AACA6BQaAABAdAoNAAAgOoUGAABQd5vBgcI6duwYxMaNG1eSXIhrnXXWyRnfdtttwZyNNtooiJ1//vlB7LvvvssZ9+zZM5izww47BLEePXoEseWWW+53soaateWWWwax//73v0GsadOmNZQRtd25556bKkb1cEUDAACITqEBAABEp9AAAACiU2gAAADRaQYHqIUaN24cxI4++uhUMairBg0aVOoUgEXgigYAABCdQgMAAIhOoQEAAESn0AAAAKJTaAAAANEpNAAAgOgUGgAAQHQKDQAAIDqFBgAAEJ1CAwAAiE6hAQAARKfQAAAAomuQZtKCBQuyf58xY0b8DChLv66FX9dGdbL+KOX6W/h9rEEyrD9KzTmYcll/qQqNmTNnZv/eoUOHP5obdUxmbbRs2bLa3yPD+qMU6+/X98mwBlmY9UepOQdT29dfvQUpypH58+cnU6ZMSZo3b57Uq1cvZo6UqcyyySywdu3aJYstVr134Fl/lHL9ZViDLMz6o9ScgymX9Zeq0AAAAFgUmsEBAIDoFBoAAEB0Cg0AACA6hQYAABCdQiOFK664Itlggw2yT1xYZpllkp49eybjx48vdVpUkOHDhye77bZb9gkPmad+DBkypNQpUUFuu+22ZM0110xatGiR/WvjjTdO/vWvf5U6LSqIz0BqiyuvvDK7Bk855ZRSp1IWFBopDBs2LDn++OOTkSNHJi+88ELy888/JzvssEMya9asUqdGhcistbXWWiu55ZZbSp0KFah9+/bZk+vo0aOTN954I9lmm22SHj16JO+++26pU6NC+AykNhg1alRy++23Z394IR2Pty3C1KlTs1c2MgXIFltsUep0qDCZX1Ief/zx7JU1KJU2bdok11xzTXL44YeXOhUqjM9ASuGHH35I1l133eTWW29NLr300mTttddObrjhhlKnVeu5olGE6dOn/+9EC1BJ5s2blwwaNCj7C3PmFiqASpC5s2WXXXZJtttuu1KnUlYalDqBcpPZITNzX96mm26adO/evdTpANSIcePGZQuLn376KVliiSWyvyivttpqpU4LoNplflwZM2ZM9tYpFo1Co4iK9p133kleeeWVUqcCUGO6dOmSjB07NntF95FHHkkOPvjg7O2jig2gLps8eXJy8sknZ3t0mzRpUup0yo5CYxGccMIJydNPP519+kWmORKgUjRq1Cjp3Llz9p/XW2+97C97N954Y7YxEqCuyjwE4+uvv872Zyx8C2nmu+DNN9+czJkzJ6lfv35Jc6zNFBopZPrlTzzxxOytAi+99FKy4oorljolgJLfRpo5wQLUZdtuu2321tGFHXrooUnXrl2Ts846S5FRgEIj5e1SAwcOTJ544onsXhpffvllNt6yZcukadOmpU6PCnnaxYcffvi/8SeffJK9jSXzQIIVVlihpLlR951zzjnJzjvvnF1rM2fOzH4eZn50ee6550qdGhXCZyClkvneV7Unt1mzZsmSSy6pVzcFj7dN+Si9fPr3758ccsghNZ4PlSfzpW7rrbcO4pn75O+9996S5ETlyDzCdujQockXX3yR/YEl8wz5zC9522+/falTo0L4DKQ22WqrrTzeNiWFBgAAEJ19NAAAgOgUGgAAQHQKDQAAIDqFBgAAEJ1CAwAAiE6hAQAARKfQAAAASrMz+Pz585MpU6Zkd0f8rc3rqCyZ7VcyOwS3a9cuWWyx6q1XrT9Kuf4yrEEWZv1Ras7BlMv6S1VoZBZYhw4dYuVHHTJ58uSkffv21foe1h+lXH8Z1iD5WH+UmnMwtX39pSo0MlXsrwds0aJFnOwoazNmzMh+8Py6NqqT9Ucp11+GNcjCrD9KzTmYUlqU9Zeq0Pj1UllmgVlkLKwmLqNaf/yWmrqMbw2Sj/VHqTkHU9vXn2ZwAAAgOoUGAAAQnUIDAACITqEBAABEp9AAAACiU2gAAADRpXq8LQBAuZgwYUIQ23HHHYMdr6uaNGlSteYFlcYVDQAAIDqFBgAAEJ1CAwAAiE6hAQAARKcZHAAoWyeeeGIQGzx4cBD79ttvc8a77bZbteYFuKIBAABUA4UGAAAQnUIDAACITqEBAABEV7HN4O+9914Qe/rpp4PY7bffnjPecMMNgznrrLNOqvc85ZRTcsaNGjVK9ToAqERfffVVzniPPfYI5owcOTKI1atXL4itscYaOeO77747So7Ab3NFAwAAiE6hAQAARKfQAAAAolNoAAAA0VVEM3jVhu6MPn36BLEffvih4LE+/vjjIDZo0KBUeay//vo542222SbV64Dyle9zJd+uxY0bN84ZjxkzJpgzc+bMIPbAAw8Esa233jpnvPzyyyexLLfcckGsR48eBT/voJAJEyYUPFe/9tprqY515ZVXFlyTSy655CLnSN2wYMGCINa7d+8g9swzzxR8kFD79u0jZ1e3uKIBAABEp9AAAACiU2gAAADRVUSPxj777BPELrzwwqJ6NP6Ivfbaq+B92jvssEO15gDUrL59+waxa665plrf81//+ldSky6//PIgtvrqqwex/fbbr+A90SuuuGLk7CgX3377bRD75z//WdSx8t03X7V3ico1e/bsIPbKK68U7It79tlngzlHHHFE5OzqFlc0AACA6BQaAABAdAoNAAAgOoUGAAAQXUU0g7dp0yaI/fWvfw1ip512WsGGoRVWWCGY8+mnn6bKY9q0aQWbijSDU9tMmjSp4J+Lhx56KJhz2223pTr+LrvskjPu379/Upc8+uij0Y611FJLBbE11lgj2vG7du0axN5///3f/RzLePPNN4PYuHHjCsbWXHPNYI5m8MrdnO8vf/lLqo3Vqnr88cdTbSIJv1p88cWD2KqrrhrEPv/885zx119/Xa151UWuaAAAANEpNAAAgOgUGgAAQHQKDQAAILqKaAbP55hjjglif//734PYW2+9lTNu0aJFtBxOOOGEaMeCRfXiiy8GscceeyyI5Wv0rtoQXK9evaLzGDlyZFKXPf/880Fs/PjxQaxLly5FNTC2bds2qUlVd8r9rYb0fA8RqOqpp54KYrvuuusfyI5ycf/996d6sErVh0XkO08vv/zykbOjEh1//PFB7D//+c/vPhyDwlzRAAAAolNoAAAA0Sk0AACA6BQaAABAdBXbDJ7P+eefH8Quu+yynPHYsWOjvd+cOXOiHQsWdvjhhwexd955J2f8+uuvF338qg9F2H///YM566+/fqqdf5s0aZLUZSuvvHKqWLnI18CdpvE733/rI444Ilpe1F4bb7xxEMt3Lu3UqVMQu/7663PGGr+pLhtuuGHBOQ8//HAQu+qqq0r+kI7azBUNAAAgOoUGAAAQnUIDAACITo/GQvbee+8gttlmm+WMd9hhh2DOuHHjovWEPProo0Udi8rw7bffBrFzzjkniN1zzz1BrE2bNgV7KM4+++wg1r179yDWtGnTnPEKK6zwO1lTLubOnRvETjrppJzxgAEDij7+q6++mjNeZ511ij4WtdcTTzyRM37ttdeCOfk2+ezVq1fBzxoopXy9tU8++WQQO/roo2soo9rPFQ0AACA6hQYAABCdQgMAAIhOoQEAAESnGXwhDzzwQBB7++23ozR+57P55ptHOxaV4ZJLLglid911V8EG3nybTy6xxBKRs6Oc/Pvf/071Gdi/f/+Cx2rUqFEQ69evXxDr1q3bIuVI7Tdt2rQgNnz48KKO1bp16yDWvn37JJYbb7wxZ/zpp5+met11110XLQcq4yEa/D+uaAAAANEpNAAAgOgUGgAAQHQKDQAAILqKaAZ///33g9gee+wRxD788MMg9ssvv1RbXrvvvnu1HZva7ccffwxiV111VRC77777freZMWPrrbcOYjvuuGMQa9KkSRGZUhe8/vrrqdZIsZ93+XZ57tChQxCrX79+Ucen9sr333TMmDE54wULFqQ61hZbbFFUDtdff32qNVn1AQWTJk0q+vifffZZznj55ZdPdSyoNK5oAAAA0Sk0AACA6BQaAABAdAoNAAAguopoBv/vf/8bxD755JMabfzO529/+1sQu+mmm2o0B0rj0ksvDWJXXnllENt3331zxjvssEMwR5M3hQwePLhaP+/mzJkTxHbZZZcgtsEGG+SMd9ttt2BOz549g9gaa6zxh3OkegwbNqzgzuD5GrM7duwYxJZccsmC7zd27Ngg9sorrwSxJ554ouCxllhiiSCWr6l7/PjxQWzvvffOGQ8aNCjVvyNUGlc0AACA6BQaAABAdAoNAAAguoro0ci3Od/VV18dxM4666wg9tNPP1VbXlOmTKm2Y1O7XXHFFanm9e7dO2esH4Ni7LXXXql61954440gNnXq1Gh5jBo16nfHGRdffHEQO+WUUwp+Xi+zzDJRcuS3zZw5M1W/Y1Xt2rULYgceeGAQW2WVVYLYhAkTCp67hwwZEsSWXnrpILb99tvnjE8//fRgzowZM1Jtijpt2rQgBoRc0QAAAKJTaAAAANEpNAAAgOgUGgAAQHQV0Qyez0knnZSqES1Nw1e+ja9OOOGEVE1mVKYNN9wwiOVrjK26jpo2bVqwwRGq2mSTTYLYM888E8Q+/fTTIPbNN9/kjL/66qtgzmOPPRbE7r777iC2YMGCgrnOnz8/iF1//fVBbMyYMTnjoUOHBnMWW8xvaTHl2xgvX6N+VUcddVQQu/DCC4NYvrXVp0+fnPE///nPYE6LFi2C2D777BPErrvuupzxBx98EMw55phjUh1/2223zRnbnA/y8ykMAABEp9AAAACiU2gAAADRKTQAAIDoKrYZPJ+dd965qNfla3D88MMPg1jfvn1zxmPHjg3mTJo0KYhpMqu9XnvttSC2zjrr5IwbNWoUzPnXv/4VxPr161dwzey9997BnJEjRwaxbt26/U7WkN8KK6yQKpbms3PLLbcMYjfffHPBPz9pvfTSSznja6+9Nphz5plnFn18Qm+//XZRr8vX+J3PHnvsEcTSrJEnnngi1fobMWJEznizzTZLlVe+hveqjeVUrjXXXLPUKdRqrmgAAADRKTQAAIDoFBoAAEB0Cg0AACA6zeARzJ07t2ATbz75moTr168fLS+K98UXXwSxXXbZJYhNnjw5iP3tb3/LGR9wwAHBnDZt2qTaTb7qOpo5c2Yw5/vvvw9iUGr51v1+++2XM95uu+2COcOGDSvq/fI9gIO4pk2bluphKD179ix4rHwPQ5k4cWLB4+fbJT5f4/eECROC2F/+8pffPfZvHT/N7udUrpVXXrnUKdRqrmgAAADRKTQAAIDoFBoAAEB0ejQiOP/884t63eGHHx7E2rdvHyEj/qh11103iE2fPj2IXX311anuTU/jhhtuKDhn++23D2Ldu3cv6v2gpjVo0KDgn7NiezRWXXXVovOiePXq1Yt2rHw9ilWPn2/TwHybSv70009BbMUVV8wZv/LKK8Gcli1bps4XKMwVDQAAIDqFBgAAEJ1CAwAAiE6hAQAAVE4z+LfffhvEDj300IIbQOXblKe6N3K74447ijrWnnvuGSEjqsNJJ50UxC655JIgduKJJ6aKpWlczbfBVKdOnXLGV1xxRTCnRYsWBd+PuivfZ9Kdd96ZM+7atWswp1evXklNmzdvXs74rbfeKvpYDRs2zBlvtNFGRR+LdHbfffdUD8R44okncsYjRowI5uT7b59vQ9KqBgwYEMTybby39NJLB7GLLrooZ7z88ssXfD8oZM6cOaVOoVZzRQMAAIhOoQEAAESn0AAAAKJTaAAAAJXTDJ6vofapp55K1UBbtcErX8NX586dg9jo0aMLHj9f49uMGTOSNE477bSccbt27VK9jpp3zjnnFGw+zRgzZkwQGzp0aMHjf//990Fsl112CWLXXXddwXVL5fjyyy+D2E477RTEqu6ePG3atKSmffXVV0Hs+uuvzxn/+9//Lvr43bp1yxlvvvnmRR+LdBo1ahTEmjVrFsRmzZqVM950002rdUfxfA/E2GeffYLYn//852jvCb965plninooTKVwRQMAAIhOoQEAAESn0AAAAKJTaAAAAJXdDP7JJ58EsZEjRwaxrbba6nd3V87XSJjxyiuvFLVTaT75duLt27dvzrhJkyZFHZvS6NOnT6lToMKdcsopBRu/88n32dmlS5cg1rRp04LHmj17dhDL95CMqo3fi/LgjKqaN28exPr161fUsSjeeuutF8QGDhxY8L/9Sy+9VPR7HnzwwTnjNddcM5izzjrrBLEtt9yy6PekMi277LJBbPXVV88Zv/vuuzWYUd3gigYAABCdQgMAAIhOoQEAAFROj8bGG2+cKnbQQQcFseOOOy5nPHHixGBOvlixWrduHcT++9//Rjs+QMa2224bxAYPHlzwdfnuYc8Xa9WqVcFj5dv8780330xiydeP8fjjjwcx9+DXDrvuumuqGJTjhpRp+tZeeOGFIGbDvv/HFQ0AACA6hQYAABCdQgMAAIhOoQEAAFROM3g++TaAmjNnThD74YcfCh4rX/PiQw89VPB1LVu2DGIvvvhiwdcB/FHbbbddEOvdu3dRn2UxG7jTatiwYcENCPfaa68gttFGG1VrXgD5rL322jnjN954o6jvnJXMFQ0AACA6hQYAABCdQgMAAIhOoQEAAFR2M3g+jRs3DmJnnHFGUccaOHBghIwAqseKK64YxPr37x/Edt9995zxv//972DOqquuGsSefPLJgjl07do1RaZJss022wSxLl26FNydHKC2OO+883LG77zzTjCnV69eNZhR+XFFAwAAiE6hAQAARKfQAAAAolNoAAAA0ZV9MzhAJcv3QIz99tvvd8e/pU+fPtHyAih3nTp1yhmPGDGiZLmUK1c0AACA6BQaAABAdAoNAAAgOoUGAAAQnUIDAACITqEBAABEp9AAAACiU2gAAADRKTQAAIDoFBoAAEB0Cg0AACA6hQYAABBdgzSTFixYkP37jBkz4mdAWfp1Lfy6NqqT9Ucp19/C72MNkmH9UWrOwZTL+ktVaMycOTP79w4dOvzR3KhjMmujZcuW1f4eGdYfpVh/v75PhjXIwqw/Ss05mNq+/uotSFGOzJ8/P5kyZUrSvHnzpF69ejFzpExllk1mgbVr1y5ZbLHqvQPP+qOU6y/DGmRh1h+l5hxMuay/VIUGAADAotAMDgAARKfQAAAAolNoAAAA0Sk0AACA6BQaKdx2223JmmuumbRo0SL718Ybb5z861//KnVaVIiLL744+6SPhf/q2rVrqdOigvgMpNQ+//zz5IADDkiWXHLJpGnTpskaa6yRvPHGG6VOiwoxfPjwZLfddss+ZSlzDh4yZEipUyobqfbRqHTt27dPrrzyymSVVVbJPtJrwIABSY8ePZI333wzWX311UudHhUgs85efPHF/40bNPBHl5rjM5BS+v7775NNN9002XrrrbMF7tJLL5188MEHSevWrUudGhVi1qxZyVprrZUcdthhyZ577lnqdMqKx9sWqU2bNsk111yTHH744aVOhQq4opH59WTs2LGlTgX+x2cgNeXss89O/u///i95+eWXS50KZK9oPP7440nPnj1LnUpZcOvUIpo3b14yaNCgbHWbuX0AakLm17vMJduVVlop2X///ZNPP/201ClRoXwGUtOefPLJZP3110/22WefZJlllknWWWed5M477yx1WkAKCo2Uxo0blyyxxBJJ48aNk2OOOSZbza622mqlTosKsNFGGyX33ntv8uyzz2bvlf/kk0+SzTffPLsrJ9QUn4GUyscff5z97Mvcuvfcc88lxx57bHLSSSdlb+EDaje3TqU0d+7c7K/I06dPTx555JHkrrvuSoYNG+ZES42bNm1a0rFjx+T666932wo1xmcgpdKoUaPsFY1XX331f7FMoTFq1KhkxIgRJc2NyuPWqUXjisYifNB17tw5WW+99ZIrrrgi2xR04403ljotKlCrVq2SVVddNfnwww9LnQoVxGcgpdK2bdugoO3WrZtbSKEMKDSKNH/+/GTOnDmlToMK9MMPPyQfffRR9uQLpeIzkJqSeeLU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fM1jxTZ+52uWzXf8jTbaKGfcpUuXVMdfcsklg9iNN95YVON3vgbN+++/P9VrqV61tSF1pZVWCmKrr756zvjdd98N5kyYMKFa86I08m1u969//StVM+TZZ5+dM7711ltTbXZ62mmnBbGnn346Z9ymTZtgzvnnnx/EjjvuuCBGeXv++eeD2KabbhrE1l133RrKiErStGnTVPPybbxXnZo3b57qgUPlxBUNAAAgOoUGAAAQnUIDAACITqEBAABUTjN4vkaxkSNHFnWsFVZYIVUz9WabbZZUp3w7PhbbjFTuzUFUr4YNG6aKURnWXnvtILbxxhunagYfOnRozviFF14I5px66qlBbNKkSQXzuvjii4PYiSeeWPB1lJeXX3451fn87bffjvaeL730UsHzZvfu3aO9H+VlwYIFqWKtW7fOGf/000/BnA8//DCIDRgwIIiNHj06Z7zccssFcwYOHBjEll9++aScuaIBAABEp9AAAACiU2gAAADRKTQAAIDKaQa/7rrrgtisWbNSvbbq7qIXXXRRtTZ+f//996l23R0+fHjBY+XbGXWXXXb5A9lRiebMmRPE8jWxVdWiRYtqyohSaty4caodaPOZMmVKznjPPfdM1URZr169IHbEEUfkjHv27JkqB8rbgw8+GMS6desWxFZaaaWCx7r33ntT7UKf77zcpEmTnPE111wTzDnhhBMK5kD5y/fgi3yfWddff33B76ZvvPFGqvccPHhwznjvvfdOKoErGgAAQHQKDQAAIDqFBgAAUDk9GkcddVQQmzp1ahBr1apVwQ1P8m2KEtPf//73IHb++ecXfF2+zYIefvjhIFbd+VP3TJw4MYi9//77BV+30047FfV+33zzTRB76623gtiIESOC2D777JMz7tKlS1E5sGg6depUrcfP11vWp0+fnHGHDh2qNQdqh3vuuSfVxmT5eonmzp2bM/7rX/8azLnjjjuC2I477hjEnnnmmZzxIYccEszp3LlztM9Faq82bdoEsRkzZgSxUaNGFdWP1qxZsyC22mqrJZXIFQ0AACA6hQYAABCdQgMAAIhOoQEAAFROM/hee+2VKlbTnnrqqSDWt2/fVK9t2LBhzvjoo48O5mj8ZlE34vvss8+C2P/93/8VdfxjjjkmiK277rpB7M0338wZf/fdd8GcTz/9NNWGgB9++GHBDbn4Y+bNmxfEXn755SCWr9ExjV133TXVZyWV4Z133skZ//zzz8GcBg3Sff0YM2ZMwcbstBuf7bvvvjnjV155JZhzxRVXBDHN4JWxYd/IkSMLnl979eqV6vj5NjZdTTM4AABAHAoNAAAgOoUGAAAQnUIDAAConGbw2qpHjx6pdoXMp1+/fgV3P6e8zJ49O4h9/fXXOePRo0cHc1577bUg9u9//7uo93v33XeTWPIda/r06QVfd9hhh6XaGXrJJZcMYiuuuOIi5cii22+//YLYo48+WvRnWazXUTd99dVXBed06dIl1bFWX331nPGll16axHLssccGse7du0c7PuXlT3/6UxAbN25cUcc699xzI2RUN7iiAQAARKfQAAAAolNoAAAA0Sk0AACA6DSDL2JDT7E752ZsueWWETKiJuRrur744ouD2JNPPhnE3n///Wh5tGzZMme8xBJLFNxx/rd24q3qyCOPLHpncGqPKVOmBLF77rknZ/zII4+kauBeb731gtiaa66ZM+7fv3/BByBAIe3bt081r3nz5iXPgcpVdZf7P/IdsFK5ogEAAESn0AAAAKJTaAAAANHp0VjI3Llzg9ibb75Z8L7mfLEbb7wxiK2yyip/OEdqRs+ePYPY888/H8SaNGkSxHbdddeCG9Ll2/ixcePGQaxTp04F7ynu2rVrEBs/fnwQW2mllXLG119/fTAnXw8ItdvQoUOD2IUXXljwdZdddlkQO+GEE4LYkCFDCvZorLbaaikypVKUy33sw4YNC2ItWrQoSS7UTk2bNi34fW+rrbYKYo0aNarWvMqJKxoAAEB0Cg0AACA6hQYAABCdQgMAAIiuYpvBf/zxxyD2wAMPpGoAruovf/lLEDvggAOC2GKLqevKRb7/7lUbszMee+yxILbOOutEy+OXX37JGZ911lnBnM8++yyILbvsskHsH//4R85Y43f5eemll4LYSSedVPB1Tz31VBDbbrvtgtiXX34ZxPr27Vvw+Pn+bFC58jXM1gZVNzK97bbbgjkHHnhgDWZEbfLf//43iN19990542WWWSaYc9xxxwUxn4n/j2++AABAdAoNAAAgOoUGAAAQnUIDAACIriKawWfOnBnEjjzyyILNsvnccMMNqXbT1fhd97Rq1SqIrbHGGtGO/9NPPwWxffbZJ2f89NNPp9qdfNCgQUFs3XXX/cM5UvseUjBt2rSCO9VW3a0+X2Psb62v6dOnF9z1eamllvqdrKk0VXeKb9u2baqHrxx77LHRcsi3vo855pic8cSJE4M59913X7QcqL2qfq5l7LTTTgUftnL11VcHc/bee+/I2dUtvg0DAADRKTQAAIDoFBoAAEB0Cg0AACC6imgGz7dzcprG74zOnTsv8i68lL8uXboEsbFjxwaxo446Koh9++23OeO11lormLPSSisFsXxNZuPHj88Z/+lPfwrm3HrrrdW6Ozm1R76HTOTbhblqLF9j7JAhQ4JYvs+31q1bF3yQRr6dcalcVZu/zz333GDOaaedlupY+++/f874o48+Cua8/fbbQezyyy8v+OCMF154IZjjwQaV4cwzz0z1XbF3794549NPP71a86qLXNEAAACiU2gAAADRKTQAAIDo6mSPxvvvv58zvv7661O9btVVVw1izz77bLS8KN81lHHBBRcEsWuvvTaIzZ8/v6g1tPvuuwexqms334ZCVI6pU6emmrf00kvnjLfffvtgzvDhw1Md6957780Z77bbbqleB7+3qW0++fo2jj/++IKva9GiRap+o/PPPz9n3KhRo1R5Ud5efPHFIHb//fcHscUXX7zgprksOlc0AACA6BQaAABAdAoNAAAgOoUGAAAQXZ1sBu/bt2/OePDgwaled+KJJwaxjh07RsuL8nbJJZekikF16datW6p5VTckXbBgQTCnTZs2qZp2t9tuu0XKEdLIt9bSNo3D75k4cWLOuFevXqleN2DAgCDWo0ePaHlVKlc0AACA6BQaAABAdAoNAAAgOoUGAAAQXdk3g7/zzjtBbObMmQVfd/TRRwexbbfdNlpeALEdfPDBQWzu3LkFH1Kw/vrrp9qJ/tRTT/3DOQLUlNmzZwexa6+9Nmc8ffr0YM7ee+8dxPbcc8/I2ZHhigYAABCdQgMAAIhOoQEAAESn0AAAAKIr+2bw+++/P4g988wzBXf3Pvnkk4NYly5dImcHEE/r1q2D2JlnnpkqBlDX9O/fP4jdeuutOeNNNtkkmHPfffdVa178P65oAAAA0Sk0AACA6BQaAABAdGXfo7HDDjsU3Kzlb3/7WzBHPwYAQHl4/fXXg9jll18exC644IKc8ZFHHhnMady4ceTs+C2uaAAAANEpNAAAgOgUGgAAQHQKDQAAILqybwbfdtttg9i8efNKkgsAAPFtuOGGQeyzzz4rSS6k54oGAAAQnUIDAACITqEBAACUpkdjwYIF2b/PmDEjfgaUpV/Xwq9rozpZf5Ry/S38PtYgGdYfpeYcTLmsv1SFxsyZM7N/79Chwx/NjTomszZatmxZ7e+RYf1RivX36/tkWIMszPqj1JyDqe3rr96CFOXI/PnzkylTpiTNmzdP6tWrFzNHylRm2WQWWLt27ZLFFqveO/CsP0q5/jKsQRZm/VFqzsGUy/pLVWgAAAAsCs3gAABAdAoNAAAgOoUGAAAQnUIDAACITqGRQqdOnbJPWqj61/HHH1/q1KgAV1xxRbLBBhtkn/ixzDLLJD179kzGjx9f6rSoIPPmzUsuuOCCZMUVV0yaNm2arLzyyskll1xSY/tIwOeff54ccMAByZJLLpldg2ussUbyxhtvlDotKkTmCUunnHJK0rFjx+z622STTZJRo0aVOq2ykGofjUqXWUyZE+2v3nnnnWT77bdP9tlnn5LmRWUYNmxYtqjNFBu//PJLcu655yY77LBD8t577yXNmjUrdXpUgKuuuiq57bbbkgEDBiSrr7569gveoYcemn1++kknnVTq9Kjjvv/++2TTTTdNtt566+Rf//pXsvTSSycffPBB0rp161KnRoU44ogjst/97r///uwjXR944IFku+22y56Hl19++VKnV6t5vG0RMlXt008/nf2g80xpatrUqVOzVzYyBcgWW2xR6nSoALvuumuy7LLLJnfffff/YnvttVf2l73MCReq09lnn5383//9X/Lyyy+XOhUq0OzZs7N3FDzxxBPJLrvs8r/4euutl+y8887JpZdeWtL8aju3Ti2iuXPnZk+shx12mCKDkpg+fXr2723atCl1KlSIzG0CQ4cOTSZMmJAdv/XWW8krr7ySPclCdXvyySeT9ddfP3sXQeZHlnXWWSe58847S50WFSJzJ0HmrpYmTZrkxDM/tGQ+B/l9Co1FNGTIkGTatGnJIYccUupUqECZHVozV9QytxF079691OlQQb8o77fffknXrl2Thg0bZr/oZdbh/vvvX+rUqAAff/xx9ta9VVZZJXnuueeSY489NnvLXuZWPqhumasZG2+8cbYvLbNDeqboyPzgPGLEiOSLL74odXq1nlunFtGOO+6YNGrUKHnqqadKnQoVKHOCzdyjnPkVpX379qVOhwoxaNCg5IwzzkiuueaabI/G2LFjs4XG9ddfnxx88MGlTo86LnPOzVzRePXVV/8XyxQamf7JzJc9qG4fffRR9k6W4cOHJ/Xr10/WXXfdZNVVV01Gjx6d/Pe//y11erWaZvBFMGnSpOTFF19MHnvssVKnQgU64YQTsr1BmQ86RQY1KVNk/HpVIyPzxJ/M52HmiWgKDapb27Ztk9VWWy0n1q1bt+TRRx8tWU5UlsyT9jJ9kbNmzUpmzJiRXZP77rtvstJKK5U6tVrPrVOLoH///tn7QxduBoLqlrnomCkyHn/88eTf//539hGjUJN+/PHHZLHFck8XmV/1MrfyQXXL3Cpa9ZHemX6hzKNGoSZlnvSYKTIyT0LL3MbXo0ePUqdU67mikVLmhJopNDK/3jVo4P82ak7m0bYDBw7MPvEic6/ol19+mY1nHi2aaUaD6rbbbrsll112WbLCCitkb5168803s7dNZW4lgOp26qmnZh9IcPnllye9evVKXn/99eSOO+7I/gU1IVNUZH7069KlS/Lhhx9mr/JmetYyj/nm9+nRSOn555/P9mdkflXJ3JcHNeW3nm6WKXw9lICa2qwqs2Ff5qra119/nX2OfO/evZMLL7wwe/88VLfMbaPnnHNO9rHymau6p512WnLkkUeWOi0qxMMPP5xdf5999ln2iY+Zx3tnfnzJ/ODH71NoAAAA0enRAAAAolNoAAAA0Sk0AACA6BQaAABAdAoNAAAgOoUGAAAQnUIDAACITqEBAABE1yDNpPnz5ydTpkxJmjdv/pu7FFNZMvs8ZnYLzuwQvNhi1VuvWn+Ucv1lWIMszPqj1JyDKZf1l6rQyCywDh06xMqPOmTy5MlJ+/btq/U9rD9Kuf4yrEHysf4oNedgavv6S1VoZKrYXw/YokWLONlR1mbMmJH94Pl1bVQn649Srr8Ma5CFWX+UmnMw5bL+UhUav14qyywwi4yF1cRlVOuP31JTl/GtQfKx/ig152Bq+/rTDA4AAESn0AAAAKJTaAAAANEpNAAAgOgUGgAAQHQKDQAAIDqFBgAAEJ1CAwAAiE6hAQAARKfQAAAAomsQ/5AAAFD39e7dO4iNHDkyiA0aNChnvNFGGyWVwBUNAAAgOoUGAAAQnUIDAACITqEBAABEpxm8Bk2YMCFnfMwxxwRzHnzwwSDWtm3bas2LyvDSSy/ljLfZZptgzoIFCwq+LmPLLbeMnB0AlJ+JEyemih1wwAE54/feey+Y07Bhw6SucUUDAACITqEBAABEp9AAAACiU2gAAADl1ww+c+bMIPbDDz8EsZYtW+aMF1988aSueeaZZ3LGw4YNC+bcddddQeycc84JYg0a6OPnt917771BrF+/fjnj+vXrB3PmzZsXxE499dQgdvDBB+eMjz/++GCONQrUZldccUUQO/fcc4PYWWedFcSuvPLKasuL2mvy5MlBbPTo0ale++GHH+aMf/nll2COZnAAAIAUFBoAAEB0Cg0AACC6ar+J+qqrrkp1X+S1115b8L7wcrfeeusVnHPxxRcHsd69ewexzp07R8uLutePcd999wWxcePGFXX8fK/r06dPzrhnz57BnI4dOxb1fpSfSZMmBbG//e1vQezWW2/NGf/888+pPu8GDhz4h3OEqj2jVfvWMurVqxfEbrjhhiC2yiqr5IwPP/zwKDlSu02bNi2I5fscy6dnlfNk48aNk0rgigYAABCdQgMAAIhOoQEAAESn0AAAAKKrNTtq/fWvf80Zr7TSSsGcHj16JOXsq6++KnUKlFmT2dixY3PGhx56aDBn6tSpQWzOnDkF369r166pNuz74IMPCh6LynHPPfcEsXwP78j3wIrbb7+94OZX+R6IceGFF6Zav/B7m6HddtttRZ2Tl1122SC28cYb/4HsKNd1lO9hRmn95S9/yRkvtlhl/NZfGf+WAABAjVJoAAAA0Sk0AACA6BQaAABA3W0Gr7pj5yGHHBLMeeGFF4LY+uuvn9RGP/zwQxC77rrrijrWww8/HMTOPffcoo5F7TBkyJAgdscddxRc8/matevXr19UDmeccUYQmz9/fhA78sgjizo+5Wfu3LkFP7f69u2bqhn8zDPPDGKtWrXKGY8ZMyZVM3jz5s1/J2sIjRgxIoidffbZRR2rahN5xmqrrVbUsSgvVT/bHnrooZLlUq5c0QAAAKJTaAAAANEpNAAAgOgUGgAAQPk1g6+44opFvW7GjBmpdod98MEHg1jr1q2TUsu3m/Lrr79eklworQceeCCIHXTQQUUda8GCBUEsX4N4scfKp9jjU3769+8fxM4777yc8Y033hjMOfHEE4t6v+effz7VLszLL798UcenMkycODGInXTSSUUda7vttgtiW2+9dVHHorzceeedQeyuu+4qSS51iSsaAABAdAoNAAAgOoUGAABQfj0a+TbemzJlSqpNmqp67rnngtijjz4axI444oik1PLdZ7zyyivnjD/66KNUx+rVq1e0vKj5noyTTz451SZ7TZo0CWLLLLNMwY0gv/vuu1R5VT1+vk3Q8vVGFbshILVbvnVzwQUXBLF99tknZ3zssccW/Z6TJk0qeE80LKrddtstiL377rsFX9eyZctUG5k2bdr0D2RHufSjnXDCCQU3MV1nnXWCOW+++Wbk7OoWVzQAAIDoFBoAAEB0Cg0AACA6hQYAAFB+zeD5GknzbaRTdeO9fBve5XPLLbcEsT322CNnvOSSSyY17auvvgpiaZu/KR9DhgwpuBlf2mbqDTfcMIgNHTo0Z3zvvfcGc4488shUx7/88stzxnvuuWcwJ9/xKX+//PJLENt0000LPnwg47bbbssZN2hQ/GnjgAMOyBl//PHHwZw+ffoUfXwq0zvvvBPE6tWrV/B1+R5ssP3220fLi+Lle/DJ2LFjg9iECRMKbo48ePDgYM60adNS5dGvX7+c8Z///OdgTufOnVMdq1K5ogEAAESn0AAAAKJTaAAAANEpNAAAgPJrBk+7G+cmm2xSVDP422+/HcQmT54crRm86q6Qt99+e6rX/eMf/yj6Pamd8jVKn3LKKQVfl2/H73yN3zfddFNRea255ppB7JBDDgliaXZ03nvvvYPYHXfcEcRGjRq1SDlSWo888kgQGz9+fBD7z3/+E8TatGlT1HsOHDgwiI0cObLg7vSawfk9p512WtGv3W677XLGF154YYSMqA5Vv8dlHH744amawdN858z3EJV8u8KvuOKKOePPPvus4PuRyxUNAAAgOoUGAAAQnUIDAACITqEBAADUjWbwfKo2gw8YMKDoY40YMSJnvPbaawdzXn311VSxqrtTXnLJJUl16tatWxBr3bp1tb4n6fTt2zeIzZo1q+Drzj333CB2zjnnFJXDZpttFsR23nnnILbssssWdfwlllgiVTM75SXf52mXLl0Kfg6n9eWXXwaxU089NYjNmzcvZ3zCCSdEW7vUTccdd1zOeMiQIalet9ZaawWxBx98MGfss632yvddKN/Df9I8OKhFixZBbIUVVkhq2qwU3xfqIlc0AACA6BQaAABAdAoNAACg7vZoHHHEETnjl156KdUGUPkcf/zxvzteFAsWLMgZ16tXL6lO7733XhDLd09qvo1riGfs2LEF+3Xy3XOeMX/+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",
            "text/plain": [
              "<Figure size 1000x1000 with 25 Axes>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "plt.figure(figsize=(10,10))\n",
        "for i in range(25):\n",
        "    plt.subplot(5,5,i+1)\n",
        "    plt.xticks([])\n",
        "    plt.yticks([])\n",
        "    plt.grid(False)\n",
        "    plt.imshow(x_train[i], cmap=plt.cm.binary)\n",
        "    plt.xlabel(y_train[i].tolist().index(1))\n",
        "plt.show()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "aVmXPQtiFX2T"
      },
      "source": [
        "# Define Model"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "8mRrfyWjFAif",
        "outputId": "f469b0d0-e7f8-4a09-94b1-163d02965352"
      },
      "outputs": [
        {
          "data": {
            "text/html": [
              "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\">Model: \"sequential\"</span>\n",
              "</pre>\n"
            ],
            "text/plain": [
              "\u001b[1mModel: \"sequential\"\u001b[0m\n"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "text/html": [
              "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓\n",
              "┃<span style=\"font-weight: bold\"> Layer (type)                    </span>┃<span style=\"font-weight: bold\"> Output Shape           </span>┃<span style=\"font-weight: bold\">       Param # </span>┃\n",
              "┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩\n",
              "│ conv2d (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Conv2D</span>)                 │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">26</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">26</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">32</span>)     │           <span style=\"color: #00af00; text-decoration-color: #00af00\">320</span> │\n",
              "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
              "│ max_pooling2d (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">MaxPooling2D</span>)    │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">13</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">13</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">32</span>)     │             <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │\n",
              "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
              "│ conv2d_1 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Conv2D</span>)               │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">11</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">11</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">64</span>)     │        <span style=\"color: #00af00; text-decoration-color: #00af00\">18,496</span> │\n",
              "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
              "│ max_pooling2d_1 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">MaxPooling2D</span>)  │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">5</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">5</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">64</span>)       │             <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │\n",
              "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
              "│ flatten (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Flatten</span>)               │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">1600</span>)           │             <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │\n",
              "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
              "│ dropout (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Dropout</span>)               │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">1600</span>)           │             <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │\n",
              "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
              "│ dense (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Dense</span>)                   │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">10</span>)             │        <span style=\"color: #00af00; text-decoration-color: #00af00\">16,010</span> │\n",
              "└─────────────────────────────────┴────────────────────────┴───────────────┘\n",
              "</pre>\n"
            ],
            "text/plain": [
              "┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓\n",
              "┃\u001b[1m \u001b[0m\u001b[1mLayer (type)                   \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1mOutput Shape          \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1m      Param #\u001b[0m\u001b[1m \u001b[0m┃\n",
              "┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩\n",
              "│ conv2d (\u001b[38;5;33mConv2D\u001b[0m)                 │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m26\u001b[0m, \u001b[38;5;34m26\u001b[0m, \u001b[38;5;34m32\u001b[0m)     │           \u001b[38;5;34m320\u001b[0m │\n",
              "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
              "│ max_pooling2d (\u001b[38;5;33mMaxPooling2D\u001b[0m)    │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m13\u001b[0m, \u001b[38;5;34m13\u001b[0m, \u001b[38;5;34m32\u001b[0m)     │             \u001b[38;5;34m0\u001b[0m │\n",
              "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
              "│ conv2d_1 (\u001b[38;5;33mConv2D\u001b[0m)               │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m11\u001b[0m, \u001b[38;5;34m11\u001b[0m, \u001b[38;5;34m64\u001b[0m)     │        \u001b[38;5;34m18,496\u001b[0m │\n",
              "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
              "│ max_pooling2d_1 (\u001b[38;5;33mMaxPooling2D\u001b[0m)  │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m5\u001b[0m, \u001b[38;5;34m5\u001b[0m, \u001b[38;5;34m64\u001b[0m)       │             \u001b[38;5;34m0\u001b[0m │\n",
              "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
              "│ flatten (\u001b[38;5;33mFlatten\u001b[0m)               │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m1600\u001b[0m)           │             \u001b[38;5;34m0\u001b[0m │\n",
              "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
              "│ dropout (\u001b[38;5;33mDropout\u001b[0m)               │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m1600\u001b[0m)           │             \u001b[38;5;34m0\u001b[0m │\n",
              "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
              "│ dense (\u001b[38;5;33mDense\u001b[0m)                   │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m10\u001b[0m)             │        \u001b[38;5;34m16,010\u001b[0m │\n",
              "└─────────────────────────────────┴────────────────────────┴───────────────┘\n"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "text/html": [
              "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Total params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">34,826</span> (136.04 KB)\n",
              "</pre>\n"
            ],
            "text/plain": [
              "\u001b[1m Total params: \u001b[0m\u001b[38;5;34m34,826\u001b[0m (136.04 KB)\n"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "text/html": [
              "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Trainable params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">34,826</span> (136.04 KB)\n",
              "</pre>\n"
            ],
            "text/plain": [
              "\u001b[1m Trainable params: \u001b[0m\u001b[38;5;34m34,826\u001b[0m (136.04 KB)\n"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "text/html": [
              "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Non-trainable params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> (0.00 B)\n",
              "</pre>\n"
            ],
            "text/plain": [
              "\u001b[1m Non-trainable params: \u001b[0m\u001b[38;5;34m0\u001b[0m (0.00 B)\n"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "model = keras.Sequential(\n",
        "    [\n",
        "        keras.Input(shape=input_shape),\n",
        "        layers.Conv2D(32, kernel_size=(3, 3), activation=\"relu\"),\n",
        "        layers.MaxPooling2D(pool_size=(2, 2)),\n",
        "        layers.Conv2D(64, kernel_size=(3, 3), activation=\"relu\"),\n",
        "        layers.MaxPooling2D(pool_size=(2, 2)),\n",
        "        layers.Flatten(),\n",
        "        layers.Dropout(0.5),\n",
        "        layers.Dense(num_classes, activation=\"softmax\"),\n",
        "    ]\n",
        ")\n",
        "\n",
        "model.summary()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Ud00t4-RFgza"
      },
      "source": [
        "\n",
        "# Train model"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "6_COrL35Fh4P",
        "outputId": "90ebe622-067f-470e-d7b3-c8a989f199d5"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Epoch 1/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9952 - loss: 0.0130 - val_accuracy: 0.9932 - val_loss: 0.0298\n",
            "Epoch 2/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9956 - loss: 0.0121 - val_accuracy: 0.9937 - val_loss: 0.0286\n",
            "Epoch 3/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9958 - loss: 0.0120 - val_accuracy: 0.9930 - val_loss: 0.0339\n",
            "Epoch 4/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 6ms/step - accuracy: 0.9962 - loss: 0.0111 - val_accuracy: 0.9930 - val_loss: 0.0330\n",
            "Epoch 5/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 6ms/step - accuracy: 0.9960 - loss: 0.0113 - val_accuracy: 0.9942 - val_loss: 0.0288\n",
            "Epoch 6/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9964 - loss: 0.0113 - val_accuracy: 0.9932 - val_loss: 0.0325\n",
            "Epoch 7/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9961 - loss: 0.0100 - val_accuracy: 0.9933 - val_loss: 0.0321\n",
            "Epoch 8/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9960 - loss: 0.0118 - val_accuracy: 0.9930 - val_loss: 0.0317\n",
            "Epoch 9/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m9s\u001b[0m 21ms/step - accuracy: 0.9962 - loss: 0.0113 - val_accuracy: 0.9937 - val_loss: 0.0335\n",
            "Epoch 10/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m12s\u001b[0m 26ms/step - accuracy: 0.9964 - loss: 0.0108 - val_accuracy: 0.9932 - val_loss: 0.0301\n",
            "Epoch 11/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m11s\u001b[0m 26ms/step - accuracy: 0.9961 - loss: 0.0105 - val_accuracy: 0.9932 - val_loss: 0.0341\n",
            "Epoch 12/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m11s\u001b[0m 26ms/step - accuracy: 0.9966 - loss: 0.0104 - val_accuracy: 0.9942 - val_loss: 0.0311\n",
            "Epoch 13/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m11s\u001b[0m 26ms/step - accuracy: 0.9962 - loss: 0.0115 - val_accuracy: 0.9933 - val_loss: 0.0299\n",
            "Epoch 14/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9956 - loss: 0.0116 - val_accuracy: 0.9933 - val_loss: 0.0316\n",
            "Epoch 15/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9967 - loss: 0.0105 - val_accuracy: 0.9935 - val_loss: 0.0330\n",
            "Epoch 16/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9962 - loss: 0.0113 - val_accuracy: 0.9937 - val_loss: 0.0324\n",
            "Epoch 17/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9959 - loss: 0.0120 - val_accuracy: 0.9935 - val_loss: 0.0302\n",
            "Epoch 18/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9962 - loss: 0.0104 - val_accuracy: 0.9930 - val_loss: 0.0312\n",
            "Epoch 19/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 6ms/step - accuracy: 0.9964 - loss: 0.0101 - val_accuracy: 0.9932 - val_loss: 0.0335\n",
            "Epoch 20/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9960 - loss: 0.0124 - val_accuracy: 0.9935 - val_loss: 0.0313\n",
            "Epoch 21/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 6ms/step - accuracy: 0.9966 - loss: 0.0094 - val_accuracy: 0.9937 - val_loss: 0.0319\n",
            "Epoch 22/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9967 - loss: 0.0102 - val_accuracy: 0.9935 - val_loss: 0.0292\n",
            "Epoch 23/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9968 - loss: 0.0089 - val_accuracy: 0.9932 - val_loss: 0.0300\n",
            "Epoch 24/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9970 - loss: 0.0093 - val_accuracy: 0.9942 - val_loss: 0.0274\n",
            "Epoch 25/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 6ms/step - accuracy: 0.9966 - loss: 0.0099 - val_accuracy: 0.9925 - val_loss: 0.0335\n",
            "Epoch 26/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 6ms/step - accuracy: 0.9966 - loss: 0.0098 - val_accuracy: 0.9935 - val_loss: 0.0318\n",
            "Epoch 27/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9968 - loss: 0.0094 - val_accuracy: 0.9940 - val_loss: 0.0323\n",
            "Epoch 28/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 6ms/step - accuracy: 0.9964 - loss: 0.0092 - val_accuracy: 0.9938 - val_loss: 0.0325\n",
            "Epoch 29/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 6ms/step - accuracy: 0.9972 - loss: 0.0085 - val_accuracy: 0.9940 - val_loss: 0.0353\n",
            "Epoch 30/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9969 - loss: 0.0096 - val_accuracy: 0.9937 - val_loss: 0.0310\n",
            "Epoch 31/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 6ms/step - accuracy: 0.9964 - loss: 0.0102 - val_accuracy: 0.9942 - val_loss: 0.0311\n",
            "Epoch 32/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9971 - loss: 0.0088 - val_accuracy: 0.9938 - val_loss: 0.0327\n",
            "Epoch 33/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 6ms/step - accuracy: 0.9962 - loss: 0.0104 - val_accuracy: 0.9938 - val_loss: 0.0333\n",
            "Epoch 34/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9971 - loss: 0.0089 - val_accuracy: 0.9938 - val_loss: 0.0313\n",
            "Epoch 35/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 6ms/step - accuracy: 0.9967 - loss: 0.0094 - val_accuracy: 0.9935 - val_loss: 0.0338\n",
            "Epoch 36/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9967 - loss: 0.0092 - val_accuracy: 0.9923 - val_loss: 0.0350\n",
            "Epoch 37/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9971 - loss: 0.0088 - val_accuracy: 0.9940 - val_loss: 0.0311\n",
            "Epoch 38/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9971 - loss: 0.0081 - val_accuracy: 0.9937 - val_loss: 0.0311\n",
            "Epoch 39/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 6ms/step - accuracy: 0.9966 - loss: 0.0084 - val_accuracy: 0.9938 - val_loss: 0.0331\n",
            "Epoch 40/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9974 - loss: 0.0080 - val_accuracy: 0.9933 - val_loss: 0.0337\n",
            "Epoch 41/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 6ms/step - accuracy: 0.9963 - loss: 0.0105 - val_accuracy: 0.9930 - val_loss: 0.0344\n",
            "Epoch 42/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 6ms/step - accuracy: 0.9972 - loss: 0.0079 - val_accuracy: 0.9930 - val_loss: 0.0386\n",
            "Epoch 43/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 6ms/step - accuracy: 0.9969 - loss: 0.0092 - val_accuracy: 0.9940 - val_loss: 0.0336\n",
            "Epoch 44/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 6ms/step - accuracy: 0.9967 - loss: 0.0093 - val_accuracy: 0.9937 - val_loss: 0.0337\n",
            "Epoch 45/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9974 - loss: 0.0089 - val_accuracy: 0.9940 - val_loss: 0.0368\n",
            "Epoch 46/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 6ms/step - accuracy: 0.9977 - loss: 0.0074 - val_accuracy: 0.9933 - val_loss: 0.0361\n",
            "Epoch 47/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9973 - loss: 0.0076 - val_accuracy: 0.9943 - val_loss: 0.0338\n",
            "Epoch 48/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9974 - loss: 0.0073 - val_accuracy: 0.9937 - val_loss: 0.0343\n",
            "Epoch 49/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9968 - loss: 0.0095 - val_accuracy: 0.9933 - val_loss: 0.0344\n",
            "Epoch 50/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9970 - loss: 0.0095 - val_accuracy: 0.9940 - val_loss: 0.0362\n",
            "Epoch 51/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9968 - loss: 0.0083 - val_accuracy: 0.9938 - val_loss: 0.0355\n",
            "Epoch 52/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9969 - loss: 0.0085 - val_accuracy: 0.9925 - val_loss: 0.0396\n",
            "Epoch 53/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9975 - loss: 0.0081 - val_accuracy: 0.9950 - val_loss: 0.0326\n",
            "Epoch 54/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9976 - loss: 0.0078 - val_accuracy: 0.9948 - val_loss: 0.0331\n",
            "Epoch 55/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 6ms/step - accuracy: 0.9969 - loss: 0.0096 - val_accuracy: 0.9938 - val_loss: 0.0346\n",
            "Epoch 56/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9974 - loss: 0.0083 - val_accuracy: 0.9948 - val_loss: 0.0318\n",
            "Epoch 57/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9973 - loss: 0.0074 - val_accuracy: 0.9937 - val_loss: 0.0363\n",
            "Epoch 58/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9969 - loss: 0.0079 - val_accuracy: 0.9935 - val_loss: 0.0355\n",
            "Epoch 59/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9969 - loss: 0.0091 - val_accuracy: 0.9943 - val_loss: 0.0348\n",
            "Epoch 60/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9972 - loss: 0.0088 - val_accuracy: 0.9937 - val_loss: 0.0351\n",
            "Epoch 61/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9969 - loss: 0.0088 - val_accuracy: 0.9942 - val_loss: 0.0346\n",
            "Epoch 62/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9972 - loss: 0.0074 - val_accuracy: 0.9938 - val_loss: 0.0369\n",
            "Epoch 63/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9965 - loss: 0.0096 - val_accuracy: 0.9937 - val_loss: 0.0343\n",
            "Epoch 64/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9970 - loss: 0.0086 - val_accuracy: 0.9937 - val_loss: 0.0357\n",
            "Epoch 65/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9976 - loss: 0.0074 - val_accuracy: 0.9938 - val_loss: 0.0373\n",
            "Epoch 66/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9974 - loss: 0.0069 - val_accuracy: 0.9938 - val_loss: 0.0356\n",
            "Epoch 67/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9977 - loss: 0.0071 - val_accuracy: 0.9935 - val_loss: 0.0380\n",
            "Epoch 68/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9974 - loss: 0.0073 - val_accuracy: 0.9938 - val_loss: 0.0370\n",
            "Epoch 69/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9978 - loss: 0.0067 - val_accuracy: 0.9942 - val_loss: 0.0383\n",
            "Epoch 70/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9970 - loss: 0.0076 - val_accuracy: 0.9932 - val_loss: 0.0369\n",
            "Epoch 71/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9974 - loss: 0.0076 - val_accuracy: 0.9938 - val_loss: 0.0335\n",
            "Epoch 72/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9975 - loss: 0.0067 - val_accuracy: 0.9940 - val_loss: 0.0338\n",
            "Epoch 73/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9969 - loss: 0.0078 - val_accuracy: 0.9935 - val_loss: 0.0367\n",
            "Epoch 74/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9976 - loss: 0.0072 - val_accuracy: 0.9937 - val_loss: 0.0352\n",
            "Epoch 75/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9972 - loss: 0.0070 - val_accuracy: 0.9930 - val_loss: 0.0356\n",
            "Epoch 76/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9978 - loss: 0.0065 - val_accuracy: 0.9940 - val_loss: 0.0360\n",
            "Epoch 77/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9972 - loss: 0.0081 - val_accuracy: 0.9942 - val_loss: 0.0359\n",
            "Epoch 78/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9980 - loss: 0.0059 - val_accuracy: 0.9938 - val_loss: 0.0361\n",
            "Epoch 79/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9969 - loss: 0.0088 - val_accuracy: 0.9938 - val_loss: 0.0357\n",
            "Epoch 80/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9973 - loss: 0.0072 - val_accuracy: 0.9933 - val_loss: 0.0374\n",
            "Epoch 81/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9978 - loss: 0.0062 - val_accuracy: 0.9942 - val_loss: 0.0353\n",
            "Epoch 82/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9976 - loss: 0.0073 - val_accuracy: 0.9942 - val_loss: 0.0367\n",
            "Epoch 83/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9975 - loss: 0.0072 - val_accuracy: 0.9948 - val_loss: 0.0363\n",
            "Epoch 84/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9976 - loss: 0.0068 - val_accuracy: 0.9942 - val_loss: 0.0403\n",
            "Epoch 85/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9969 - loss: 0.0074 - val_accuracy: 0.9937 - val_loss: 0.0393\n",
            "Epoch 86/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9976 - loss: 0.0074 - val_accuracy: 0.9942 - val_loss: 0.0367\n",
            "Epoch 87/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9982 - loss: 0.0056 - val_accuracy: 0.9942 - val_loss: 0.0392\n",
            "Epoch 88/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9975 - loss: 0.0068 - val_accuracy: 0.9945 - val_loss: 0.0370\n",
            "Epoch 89/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9975 - loss: 0.0061 - val_accuracy: 0.9942 - val_loss: 0.0383\n",
            "Epoch 90/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9979 - loss: 0.0058 - val_accuracy: 0.9933 - val_loss: 0.0381\n",
            "Epoch 91/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9976 - loss: 0.0076 - val_accuracy: 0.9937 - val_loss: 0.0376\n",
            "Epoch 92/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9972 - loss: 0.0078 - val_accuracy: 0.9945 - val_loss: 0.0360\n",
            "Epoch 93/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9982 - loss: 0.0053 - val_accuracy: 0.9942 - val_loss: 0.0359\n",
            "Epoch 94/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9977 - loss: 0.0066 - val_accuracy: 0.9930 - val_loss: 0.0366\n",
            "Epoch 95/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9977 - loss: 0.0066 - val_accuracy: 0.9938 - val_loss: 0.0366\n",
            "Epoch 96/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9977 - loss: 0.0066 - val_accuracy: 0.9938 - val_loss: 0.0388\n",
            "Epoch 97/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9975 - loss: 0.0065 - val_accuracy: 0.9942 - val_loss: 0.0391\n",
            "Epoch 98/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9973 - loss: 0.0075 - val_accuracy: 0.9942 - val_loss: 0.0353\n",
            "Epoch 99/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9977 - loss: 0.0072 - val_accuracy: 0.9940 - val_loss: 0.0402\n",
            "Epoch 100/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9978 - loss: 0.0067 - val_accuracy: 0.9933 - val_loss: 0.0392\n",
            "Epoch 101/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9972 - loss: 0.0076 - val_accuracy: 0.9942 - val_loss: 0.0369\n",
            "Epoch 102/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9979 - loss: 0.0068 - val_accuracy: 0.9930 - val_loss: 0.0437\n",
            "Epoch 103/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9980 - loss: 0.0059 - val_accuracy: 0.9938 - val_loss: 0.0385\n",
            "Epoch 104/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9977 - loss: 0.0075 - val_accuracy: 0.9937 - val_loss: 0.0381\n",
            "Epoch 105/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9974 - loss: 0.0070 - val_accuracy: 0.9942 - val_loss: 0.0362\n",
            "Epoch 106/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9979 - loss: 0.0074 - val_accuracy: 0.9937 - val_loss: 0.0376\n",
            "Epoch 107/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9978 - loss: 0.0063 - val_accuracy: 0.9925 - val_loss: 0.0393\n",
            "Epoch 108/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9977 - loss: 0.0064 - val_accuracy: 0.9937 - val_loss: 0.0385\n",
            "Epoch 109/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9975 - loss: 0.0068 - val_accuracy: 0.9938 - val_loss: 0.0372\n",
            "Epoch 110/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9982 - loss: 0.0059 - val_accuracy: 0.9930 - val_loss: 0.0424\n",
            "Epoch 111/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9977 - loss: 0.0078 - val_accuracy: 0.9937 - val_loss: 0.0392\n",
            "Epoch 112/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9982 - loss: 0.0053 - val_accuracy: 0.9935 - val_loss: 0.0432\n",
            "Epoch 113/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9980 - loss: 0.0058 - val_accuracy: 0.9930 - val_loss: 0.0399\n",
            "Epoch 114/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9980 - loss: 0.0055 - val_accuracy: 0.9925 - val_loss: 0.0445\n",
            "Epoch 115/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9970 - loss: 0.0080 - val_accuracy: 0.9925 - val_loss: 0.0422\n",
            "Epoch 116/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9973 - loss: 0.0078 - val_accuracy: 0.9937 - val_loss: 0.0386\n",
            "Epoch 117/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9980 - loss: 0.0056 - val_accuracy: 0.9928 - val_loss: 0.0409\n",
            "Epoch 118/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9978 - loss: 0.0057 - val_accuracy: 0.9937 - val_loss: 0.0421\n",
            "Epoch 119/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9979 - loss: 0.0064 - val_accuracy: 0.9933 - val_loss: 0.0404\n",
            "Epoch 120/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9978 - loss: 0.0060 - val_accuracy: 0.9932 - val_loss: 0.0405\n",
            "Epoch 121/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9973 - loss: 0.0081 - val_accuracy: 0.9940 - val_loss: 0.0404\n",
            "Epoch 122/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9975 - loss: 0.0075 - val_accuracy: 0.9937 - val_loss: 0.0369\n",
            "Epoch 123/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9977 - loss: 0.0067 - val_accuracy: 0.9937 - val_loss: 0.0401\n",
            "Epoch 124/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9980 - loss: 0.0063 - val_accuracy: 0.9935 - val_loss: 0.0382\n",
            "Epoch 125/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9983 - loss: 0.0055 - val_accuracy: 0.9935 - val_loss: 0.0440\n",
            "Epoch 126/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9982 - loss: 0.0058 - val_accuracy: 0.9933 - val_loss: 0.0402\n",
            "Epoch 127/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9982 - loss: 0.0049 - val_accuracy: 0.9937 - val_loss: 0.0436\n",
            "Epoch 128/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9984 - loss: 0.0051 - val_accuracy: 0.9933 - val_loss: 0.0406\n",
            "Epoch 129/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9976 - loss: 0.0080 - val_accuracy: 0.9935 - val_loss: 0.0442\n",
            "Epoch 130/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9976 - loss: 0.0068 - val_accuracy: 0.9930 - val_loss: 0.0425\n",
            "Epoch 131/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9980 - loss: 0.0067 - val_accuracy: 0.9942 - val_loss: 0.0386\n",
            "Epoch 132/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9981 - loss: 0.0054 - val_accuracy: 0.9935 - val_loss: 0.0412\n",
            "Epoch 133/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9988 - loss: 0.0036 - val_accuracy: 0.9927 - val_loss: 0.0450\n",
            "Epoch 134/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9975 - loss: 0.0071 - val_accuracy: 0.9923 - val_loss: 0.0419\n",
            "Epoch 135/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9983 - loss: 0.0056 - val_accuracy: 0.9937 - val_loss: 0.0412\n",
            "Epoch 136/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9981 - loss: 0.0049 - val_accuracy: 0.9935 - val_loss: 0.0410\n",
            "Epoch 137/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9980 - loss: 0.0059 - val_accuracy: 0.9933 - val_loss: 0.0419\n",
            "Epoch 138/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9979 - loss: 0.0055 - val_accuracy: 0.9930 - val_loss: 0.0429\n",
            "Epoch 139/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9982 - loss: 0.0059 - val_accuracy: 0.9937 - val_loss: 0.0429\n",
            "Epoch 140/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9977 - loss: 0.0070 - val_accuracy: 0.9933 - val_loss: 0.0413\n",
            "Epoch 141/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9981 - loss: 0.0059 - val_accuracy: 0.9935 - val_loss: 0.0430\n",
            "Epoch 142/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9971 - loss: 0.0087 - val_accuracy: 0.9937 - val_loss: 0.0448\n",
            "Epoch 143/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9981 - loss: 0.0065 - val_accuracy: 0.9933 - val_loss: 0.0420\n",
            "Epoch 144/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9970 - loss: 0.0085 - val_accuracy: 0.9938 - val_loss: 0.0390\n",
            "Epoch 145/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9981 - loss: 0.0057 - val_accuracy: 0.9935 - val_loss: 0.0394\n",
            "Epoch 146/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9981 - loss: 0.0054 - val_accuracy: 0.9930 - val_loss: 0.0446\n",
            "Epoch 147/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9982 - loss: 0.0051 - val_accuracy: 0.9933 - val_loss: 0.0413\n",
            "Epoch 148/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9976 - loss: 0.0071 - val_accuracy: 0.9935 - val_loss: 0.0440\n",
            "Epoch 149/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9980 - loss: 0.0061 - val_accuracy: 0.9937 - val_loss: 0.0397\n",
            "Epoch 150/150\n",
            "\u001b[1m422/422\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 7ms/step - accuracy: 0.9978 - loss: 0.0061 - val_accuracy: 0.9928 - val_loss: 0.0443\n"
          ]
        },
        {
          "data": {
            "text/plain": [
              "<keras.src.callbacks.history.History at 0x1ff8389cef0>"
            ]
          },
          "execution_count": 23,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "batch_size = 128\n",
        "epochs = 150\n",
        "\n",
        "model.compile(loss=\"categorical_crossentropy\", optimizer=\"adam\", metrics=[\"accuracy\"])\n",
        "\n",
        "model.fit(x_train, y_train, batch_size=batch_size, epochs=epochs, validation_split=0.1)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "-k_wXsaHFoPI"
      },
      "source": [
        "# Evaluate the trained model"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 24,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "WOKRmZG6Fnxl",
        "outputId": "a779154a-32e8-431b-af2c-4f2dbfef82f9"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Test loss: 0.03142034262418747\n",
            "Test accuracy: 0.993399977684021\n"
          ]
        }
      ],
      "source": [
        "score = model.evaluate(x_test, y_test, verbose=0)\n",
        "print(\"Test loss:\", score[0])\n",
        "print(\"Test accuracy:\", score[1])"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "wCiAQH4aFuns"
      },
      "source": [
        "# Full Integer Quantization\n",
        "ref: https://www.tensorflow.org/lite/performance/post_training_quantization#full_integer_quantization"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 25,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "yRjpzBK8FuGr",
        "outputId": "e5a8e0a4-e559-4df6-9c57-bb19a466375b"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "INFO:tensorflow:Assets written to: C:\\Users\\27844\\AppData\\Local\\Temp\\tmp46n3xmvc\\assets\n"
          ]
        },
        {
          "name": "stderr",
          "output_type": "stream",
          "text": [
            "INFO:tensorflow:Assets written to: C:\\Users\\27844\\AppData\\Local\\Temp\\tmp46n3xmvc\\assets\n"
          ]
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Saved artifact at 'C:\\Users\\27844\\AppData\\Local\\Temp\\tmp46n3xmvc'. The following endpoints are available:\n",
            "\n",
            "* Endpoint 'serve'\n",
            "  args_0 (POSITIONAL_ONLY): TensorSpec(shape=(None, 28, 28, 1), dtype=tf.float32, name='keras_tensor')\n",
            "Output Type:\n",
            "  TensorSpec(shape=(None, 10), dtype=tf.float32, name=None)\n",
            "Captures:\n",
            "  2198952750224: TensorSpec(shape=(), dtype=tf.resource, name=None)\n",
            "  2198952751760: TensorSpec(shape=(), dtype=tf.resource, name=None)\n",
            "  2198952750992: TensorSpec(shape=(), dtype=tf.resource, name=None)\n",
            "  2198952753296: TensorSpec(shape=(), dtype=tf.resource, name=None)\n",
            "  2198952753104: TensorSpec(shape=(), dtype=tf.resource, name=None)\n",
            "  2198952752144: TensorSpec(shape=(), dtype=tf.resource, name=None)\n"
          ]
        },
        {
          "name": "stderr",
          "output_type": "stream",
          "text": [
            "c:\\Users\\27844\\Workspace\\diansai\\openmv\\openmv-M7\\.venv\\Lib\\site-packages\\tensorflow\\lite\\python\\convert.py:854: UserWarning: Statistics for quantized inputs were expected, but not specified; continuing anyway.\n",
            "  warnings.warn(\n"
          ]
        }
      ],
      "source": [
        "import tensorflow as tf\n",
        "from tensorflow import lite\n",
        "\n",
        "def representative_dataset():\n",
        "    for i in range(100):\n",
        "        yield [np.array([x_test[i]])]\n",
        "\n",
        "# Convert the tflite.\n",
        "converter = lite.TFLiteConverter.from_keras_model(model)\n",
        "converter.optimizations = [lite.Optimize.DEFAULT]\n",
        "converter.representative_dataset = representative_dataset\n",
        "converter.target_spec.supported_ops = [lite.OpsSet.TFLITE_BUILTINS_INT8]\n",
        "converter.inference_input_type = tf.int8\n",
        "converter.inference_output_type = tf.int8\n",
        "tflite_quant_model = converter.convert()\n",
        "\n",
        "# Save the model.\n",
        "with open('trained_180.tflite', 'wb') as f:\n",
        "  f.write(tflite_quant_model)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "SWoD4t6YF8Sz"
      },
      "source": [
        "# Succeed\n",
        "Copy trained.tflite to OpenMV4 H7 or OpenMV4 H7 Plus, run this code in OpenMV: https://github.com/SingTown/openmv_tensorflow_training_scripts/blob/main/mnist/main.py"
      ]
    }
  ],
  "metadata": {
    "colab": {
      "authorship_tag": "ABX9TyM27GgDK7Wum7qIaf7b+7i0",
      "include_colab_link": true,
      "provenance": []
    },
    "kernelspec": {
      "display_name": ".venv",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3.12.8"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}
